---
title: Docs > Core Library > TypedRoute
---
import { Callout, Tabs } from 'nextra/components'

## Outline
```typescript filename="@nestia/core" showLineNumbers
export namespace TypedRoute {
  export function Get(path?: string): MethodDecorator;
  export function Post(path?: string): MethodDecorator;
  export function Put(path?: string): MethodDecorator;
  export function Patch(path?: string): MethodDecorator;
  export function Delete(path?: string): MethodDecorator;
}
```

Route decorators **200x faster**, even **type safe** and **easy to use**.

`TypedRoute` is a namespaced module containing router decorators utilizing [`typia.assertStringify<T>()`](https://typia.io/docs/json/stringify/) function. Those decorators are almost same with original `NestJS`, but `TypedRoute` can boost up JSON serialization speed maximum 200x times faster than `class-transformer`, therefore much faster than original `NestJS`. 

Furthermore, as `TypedRoute` utilizes [`typia.assertStringify<T>()`](https://typia.io/docs/json/stringify) function, it is even type safe. The [`typia.assertStringify<T>()`](https://typia.io/docs/json/stringify) function validates response data type, via [`typia.assert<T>()`](https://typia.io/docs/validators/assert) function, before JSON serialization. Therefore, if you try to return wrong typed value, it would be blocked with 500 internal server error.

Moreover, `TypedRoute` is much easier than `class-transformer`, because it just needs only pure TypeScript type definition. If you can't understand the word "pure TypeScript type", then move to below [**#How to use**](#how-to-use) section and read the `IBbsArticle` interface type. You may understand what it means.

<Callout type="info">

If you want `application/x-www-form-urlencoded` type, use [`@TypedQuery.Post()`](./TypedQuery#typedquerypost) instead.

</Callout>

<Callout type="warning">

`@TypedRoute.Get()` is not essential for [Swagger Documents](./sdk/swagger) or [SDK Library](./sdk/sdk) building.

Therefore, it is not a matter to use `@TypedRoute.Post()` or `@Post()` of the original NestJS.

</Callout>




## How to use
<Tabs 
  items={[
      <code>IBbsArticle.ts</code>,
      <code>BbsArticlesController.ts</code>,
      'Compiled JavaScript File'
  ]}
  defaultIndex={1}>
  <Tabs.Tab>
```typescript copy filename="IBbsArticle.ts" showLineNumbers
import { tags } from "typia";

export interface IBbsArticle extends IBbsArticle.IStore {
  id: string & tags.Format<"uuid">;
  created_at: string & tags.Format<"date-time">;
}
export namespace IBbsArticle {
  export interface IStore {
    title: string & tags.MinLength<3> & tags.MaxLength<50>;
    body: string;
    files: IAttachmentFile[];
  }
}

export interface IAttachmentFile {
  name: null | (string & tags.MinLength<1> & tags.MaxLength<255>);
  extension: null | (string & tags.MinLength<1> & tags.MaxLength<8>);
  url: string & tags.Format<"url">;
}
```
  </Tabs.Tab>
  <Tabs.Tab>
```typescript copy filename="BbsArticlesController.ts" showLineNumbers {11-12}
import { TypedRoute } from "@nestia/core";
import { Controller } from "@nestjs/common";

import { IBbsArticle } from "./IBbsArticle";

@Controller("bbs/articles")
export class BbsArticlesController {
  /**
   * Get random article for testing.
   */
  @TypedRoute.Get("random")
  public async random(): Promise<IBbsArticle> {
    return {
      id: "2b5e21d8-0e44-4482-bd3e-4540dee7f3d6",
      title: "Hello nestia users",
      body: "Just use `TypedRoute.Get()` function like this",
      created_at: "2023-04-23T12:04:54.168Z",
      files: [],
    };
  }
}
```
  </Tabs.Tab>
  <Tabs.Tab>
```javascript filename="BbsArticlesController.js" showLineNumbers {41-150}
"use strict";
var __decorate =
  (this && this.__decorate) ||
  function (decorators, target, key, desc) {
    var c = arguments.length,
      r =
        c < 3
          ? target
          : desc === null
          ? (desc = Object.getOwnPropertyDescriptor(target, key))
          : desc,
      d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
      r = Reflect.decorate(decorators, target, key, desc);
    else
      for (var i = decorators.length - 1; i >= 0; i--)
        if ((d = decorators[i]))
          r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
  };
var __metadata =
  (this && this.__metadata) ||
  function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
      return Reflect.metadata(k, v);
  };
var __awaiter =
  (this && this.__awaiter) ||
  function (thisArg, _arguments, P, generator) {
    function adopt(value) {
      return value instanceof P
        ? value
        : new P(function (resolve) {
            resolve(value);
          });
    }
    return new (P || (P = Promise))(function (resolve, reject) {
      function fulfilled(value) {
        try {
          step(generator.next(value));
        } catch (e) {
          reject(e);
        }
      }
      function rejected(value) {
        try {
          step(generator["throw"](value));
        } catch (e) {
          reject(e);
        }
      }
      function step(result) {
        result.done
          ? resolve(result.value)
          : adopt(result.value).then(fulfilled, rejected);
      }
      step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
  };
Object.defineProperty(exports, "__esModule", { value: true });
exports.BbsArticlesController = void 0;
const core_1 = require("@nestia/core");
const common_1 = require("@nestjs/common");
let BbsArticlesController = class BbsArticlesController {
  /**
   * Get random article for testing.
   */
  random() {
    return __awaiter(this, void 0, void 0, function* () {
      return {
        id: "2b5e21d8-0e44-4482-bd3e-4540dee7f3d6",
        title: "Hello nestia users",
        body: "Just use `TypedRoute.Get()` function like this",
        created_at: "2023-04-23T12:04:54.168Z",
        files: [],
      };
    });
  }
};
exports.BbsArticlesController = BbsArticlesController;
__decorate(
  [
    core_1.TypedRoute.Get("random", {
      type: "assert",
      assert: (input) => {
        const assert = (input) => {
          const __is = (input) => {
            const $io0 = (input) =>
              "string" === typeof input.id &&
              /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i.test(
                input.id,
              ) &&
              "string" === typeof input.created_at &&
              !isNaN(new Date(input.created_at).getTime()) &&
              "string" === typeof input.title &&
              3 <= input.title.length &&
              input.title.length <= 50 &&
              "string" === typeof input.body &&
              Array.isArray(input.files) &&
              input.files.every(
                (elem) =>
                  "object" === typeof elem && null !== elem && $io1(elem),
              );
            const $io1 = (input) =>
              (null === input.name ||
                ("string" === typeof input.name &&
                  1 <= input.name.length &&
                  input.name.length <= 255)) &&
              (null === input.extension ||
                ("string" === typeof input.extension &&
                  1 <= input.extension.length &&
                  input.extension.length <= 8)) &&
              "string" === typeof input.url &&
              /^[a-zA-Z0-9]+:\/\/(?:www.)?[-a-zA-Z0-9@:%._+~#=]{1,256}.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_+.~#?&/=]*)$/.test(
                input.url,
              );
            return "object" === typeof input && null !== input && $io0(input);
          };
          if (false === __is(input))
            ((input, _path, _exceptionable = true) => {
              const $guard = core_1.TypedRoute.Get.guard;
              const $ao0 = (input, _path, _exceptionable = true) =>
                (("string" === typeof input.id &&
                  (/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i.test(
                    input.id,
                  ) ||
                    $guard(_exceptionable, {
                      path: _path + ".id",
                      expected: 'string & Format<"uuid">',
                      value: input.id,
                    }))) ||
                  $guard(_exceptionable, {
                    path: _path + ".id",
                    expected: '(string & Format<"uuid">)',
                    value: input.id,
                  })) &&
                (("string" === typeof input.created_at &&
                  (!isNaN(new Date(input.created_at).getTime()) ||
                    $guard(_exceptionable, {
                      path: _path + ".created_at",
                      expected: 'string & Format<"date-time">',
                      value: input.created_at,
                    }))) ||
                  $guard(_exceptionable, {
                    path: _path + ".created_at",
                    expected: '(string & Format<"date-time">)',
                    value: input.created_at,
                  })) &&
                (("string" === typeof input.title &&
                  (3 <= input.title.length ||
                    $guard(_exceptionable, {
                      path: _path + ".title",
                      expected: "string & MinLength<3>",
                      value: input.title,
                    })) &&
                  (input.title.length <= 50 ||
                    $guard(_exceptionable, {
                      path: _path + ".title",
                      expected: "string & MaxLength<50>",
                      value: input.title,
                    }))) ||
                  $guard(_exceptionable, {
                    path: _path + ".title",
                    expected: "(string & MinLength<3> & MaxLength<50>)",
                    value: input.title,
                  })) &&
                ("string" === typeof input.body ||
                  $guard(_exceptionable, {
                    path: _path + ".body",
                    expected: "string",
                    value: input.body,
                  })) &&
                (((Array.isArray(input.files) ||
                  $guard(_exceptionable, {
                    path: _path + ".files",
                    expected: "Array<IAttachmentFile>",
                    value: input.files,
                  })) &&
                  input.files.every(
                    (elem, _index1) =>
                      ((("object" === typeof elem && null !== elem) ||
                        $guard(_exceptionable, {
                          path: _path + ".files[" + _index1 + "]",
                          expected: "IAttachmentFile",
                          value: elem,
                        })) &&
                        $ao1(
                          elem,
                          _path + ".files[" + _index1 + "]",
                          true && _exceptionable,
                        )) ||
                      $guard(_exceptionable, {
                        path: _path + ".files[" + _index1 + "]",
                        expected: "IAttachmentFile",
                        value: elem,
                      }),
                  )) ||
                  $guard(_exceptionable, {
                    path: _path + ".files",
                    expected: "Array<IAttachmentFile>",
                    value: input.files,
                  }));
              const $ao1 = (input, _path, _exceptionable = true) =>
                (null === input.name ||
                  ("string" === typeof input.name &&
                    (1 <= input.name.length ||
                      $guard(_exceptionable, {
                        path: _path + ".name",
                        expected: "string & MinLength<1>",
                        value: input.name,
                      })) &&
                    (input.name.length <= 255 ||
                      $guard(_exceptionable, {
                        path: _path + ".name",
                        expected: "string & MaxLength<255>",
                        value: input.name,
                      }))) ||
                  $guard(_exceptionable, {
                    path: _path + ".name",
                    expected:
                      "((string & MinLength<1> & MaxLength<255>) | null)",
                    value: input.name,
                  })) &&
                (null === input.extension ||
                  ("string" === typeof input.extension &&
                    (1 <= input.extension.length ||
                      $guard(_exceptionable, {
                        path: _path + ".extension",
                        expected: "string & MinLength<1>",
                        value: input.extension,
                      })) &&
                    (input.extension.length <= 8 ||
                      $guard(_exceptionable, {
                        path: _path + ".extension",
                        expected: "string & MaxLength<8>",
                        value: input.extension,
                      }))) ||
                  $guard(_exceptionable, {
                    path: _path + ".extension",
                    expected: "((string & MinLength<1> & MaxLength<8>) | null)",
                    value: input.extension,
                  })) &&
                (("string" === typeof input.url &&
                  (/^[a-zA-Z0-9]+:\/\/(?:www.)?[-a-zA-Z0-9@:%._+~#=]{1,256}.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_+.~#?&/=]*)$/.test(
                    input.url,
                  ) ||
                    $guard(_exceptionable, {
                      path: _path + ".url",
                      expected: 'string & Format<"url">',
                      value: input.url,
                    }))) ||
                  $guard(_exceptionable, {
                    path: _path + ".url",
                    expected: '(string & Format<"url">)',
                    value: input.url,
                  }));
              return (
                ((("object" === typeof input && null !== input) ||
                  $guard(true, {
                    path: _path + "",
                    expected: "IBbsArticle",
                    value: input,
                  })) &&
                  $ao0(input, _path + "", true)) ||
                $guard(true, {
                  path: _path + "",
                  expected: "IBbsArticle",
                  value: input,
                })
              );
            })(input, "$input", true);
          return input;
        };
        const stringify = (input) => {
          const $io1 = (input) =>
            (null === input.name ||
              ("string" === typeof input.name &&
                1 <= input.name.length &&
                input.name.length <= 255)) &&
            (null === input.extension ||
              ("string" === typeof input.extension &&
                1 <= input.extension.length &&
                input.extension.length <= 8)) &&
            "string" === typeof input.url &&
            /^[a-zA-Z0-9]+:\/\/(?:www.)?[-a-zA-Z0-9@:%._+~#=]{1,256}.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_+.~#?&/=]*)$/.test(
              input.url,
            );
          const $string = core_1.TypedRoute.Get.string;
          const $so0 = (input) =>
            `{"id":${$string(input.id)},"created_at":${$string(
              input.created_at,
            )},"title":${$string(input.title)},"body":${$string(
              input.body,
            )},"files":${`[${input.files
              .map((elem) => $so1(elem))
              .join(",")}]`}}`;
          const $so1 = (input) =>
            `{"name":${
              null !== input.name ? $string(input.name) : "null"
            },"extension":${
              null !== input.extension ? $string(input.extension) : "null"
            },"url":${$string(input.url)}}`;
          return $so0(input);
        };
        return stringify(assert(input));
      },
    }),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", []),
    __metadata("design:returntype", Promise),
  ],
  BbsArticlesController.prototype,
  "random",
  null,
);
exports.BbsArticlesController = BbsArticlesController = __decorate(
  [(0, common_1.Controller)("bbs/articles")],
  BbsArticlesController,
);
```
  </Tabs.Tab>
</Tabs>

Just call `@TypedRoute.${method}()` function on the target method, that's all.

`Nestia` will analyze your type (`IBbsArticle`), and writes optimal code for the target type, in the compilation level. If you click the "Compiled JavaScript File" tab of above, you can see the optimal validation and JSON serialization code. 

Such optimization is called AOT (Ahead of Time) compilation, and it is the secret of `TypedRoute`.




## Special Tags
You can enhance validation logic, of `TypedRoute`, through comment tags.

You know what? `@TypedRoute.${method}()` functions are using [`typia.assertStringify<T>()`](https://typia.io/docs/json/stringify) function, that is combined with [`typia.assert<T>()`](https://typia.io/docs/validators/assert) and `typia.stringify<T>()` functions. It is the secret of `@TypedRoute.${method}()` functions, which can validates response body data type before JSON serialization, and throws 500 internal server error when the data type is not matched.

Also, as [`typia.assert<T>()`](https://typia.io/docs/validators/assert) function can utililze comment tags for additional validation, `TypedRoute` also can utillze them, too. For reference, "Type Tag" means a intersection type with atomic type and special tag type of `typia` like `number & tags.Type<"uint32">`, and "Comment Tag" means a comment starting from `@` symbol following `@${name} ${value}` format.

With those type and comment tags, you can add additional validation logics. If you want to add a custom validation logic, you also can do it. Read below Guide Documents of [typia](https://typia.io), and see the example code. You may understand how to utilize such type and comment tags, in a few minutes.

  - [**`typia` > Validators > Custom Tags**](https://typia.io/docs/validators/tags/)
    - [Outline](https://typia.io/docs/validators/tags/#outline)
    - [Type Tags](https://typia.io/docs/validators/tags/#type-tags)
    - [Comment Tags](https://typia.io/docs/validators/tags/#comment-tags)
    - [Customization](https://typia.io/docs/validators/tags/#customization)

<Tabs items={['TypeScript Source Code', 'Compiled JavaScript File']}>
  <Tabs.Tab>
```typescript copy filename="examples/src/is-special-tags.ts" showLineNumbers {3}
import typia, { tags } from "typia";

export const checkSpecialTag = typia.createIs<SpecialTag>();

interface SpecialTag {
  int32: number & tags.Type<"int32">;
  range?: number & tags.ExclusiveMinimum<19> & tags.Maximum<100>;
  minLength: string & tags.MinLength<3>;
  pattern: string & tags.Pattern<"^[a-z]+$">;
  date: null | (string & tags.Format<"date">);
  ip: string & (tags.Format<"ipv4"> | tags.Format<"ipv6">);
  uuids: Array<string & tags.Format<"uuid">> &
    tags.MinItems<3> &
    tags.MaxItems<100>;
}
```
  </Tabs.Tab>
  <Tabs.Tab>
```javascript filename="examples/bin/is-special-tags.js" showLineNumbers {10-45}
"use strict";
var __importDefault =
  (this && this.__importDefault) ||
  function (mod) {
    return mod && mod.__esModule ? mod : { default: mod };
  };
Object.defineProperty(exports, "__esModule", { value: true });
exports.checkSpecialTag = void 0;
const typia_1 = __importDefault(require("typia"));
const checkSpecialTag = (input) => {
  const $io0 = (input) =>
    "number" === typeof input.int32 &&
    Math.floor(input.int32) === input.int32 &&
    -2147483648 <= input.int32 &&
    input.int32 <= 2147483647 &&
    (undefined === input.range ||
      ("number" === typeof input.range &&
        19 < input.range &&
        input.range <= 100)) &&
    "string" === typeof input.minLength &&
    3 <= input.minLength.length &&
    "string" === typeof input.pattern &&
    /^[a-z]+$/.test(input.pattern) &&
    (null === input.date ||
      ("string" === typeof input.date &&
        /^(d{4})-(d{2})-(d{2})$/.test(input.date))) &&
    "string" === typeof input.ip &&
    (/^(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(
      input.ip,
    ) ||
      /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/.test(
        input.ip,
      )) &&
    Array.isArray(input.uuids) &&
    3 <= input.uuids.length &&
    input.uuids.length <= 100 &&
    input.uuids.every(
      (elem) =>
        "string" === typeof elem &&
        /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i.test(
          elem,
        ),
    );
  return "object" === typeof input && null !== input && $io0(input);
};
exports.checkSpecialTag = checkSpecialTag;
```
  </Tabs.Tab>
</Tabs>




## `EncryptedRoute`
```typescript filename="@nestia/core"
export namespace EncryptedRoute {
  export function Get(path?: string): MethodDecorator;
  export function Post(path?: string): MethodDecorator;
  export function Put(path?: string): MethodDecorator;
  export function Patch(path?: string): MethodDecorator;
  export function Delete(path?: string): MethodDecorator;
}
```

Encrypted router decorator functions.

`EncryptedRoute` is a namespaced module similar with `TypedRoute`, but it encrypts response body data through AES-128/256 CBC algorithm like below. Therefore, it would be slower than `TypedRoute`, but it guarantees the security of response body data.

  - AES-128/256
  - CBC mode
  - PKCS #5 Padding
  - Base64 Encoding

For reference, such encryption spec is not supported in the [Swagger-UI](../sdk/swagger). Instead, [SDK (Software Development Kit)](../sdk/sdk) generated by `@nestia/sdk` supports it. Thus, you have to build and distribute the SDK library to the client developers when using such encryption decorators.




## Configuration
```json filename="tsconfig.json" showLineNumbers {8}
{
  "compilerOptions": {
    "strict": true,
    "plugins": [
      { "transform": "typia/lib/transform" },
      {
        "transform": "@nestia/core/lib/transform",
        "stringify": "assert",
        // "llm": {
        //   "model": "chatgpt",
        //   "strict": true,
        // },
      }
    ]
  }
}
```

Change JSON serializer to another one.

If you configure `stringify` property of plugin defined in the `tsconfig.json` file, you can change the `@TypedRoute` module to utilize another JSON serialization function instead of the default [`typia.json.assertStringify<T>()`](https://typia.io/docs/json/stringify/) function. For example, if you change the property to `"validate"`, the JSON serialization function of `@TypedRoute` module be changed to [`typia.json.validateStringify()`](https://typia.io/docs/json/stringify/) function.

Here is the list of available options.

  - `stringify`: [`typia.json.stringify<T>()`](https://typia.io/docs/json/stringify/)
  - `assert`: [`typia.json.assertStringify<T>()`](https://typia.io/docs/json/stringify/)
  - `is`: [`typia.json.isStringify<T>()`](https://typia.io/docs/json/stringify/)
  - `validate`: [`typia.json.validateStringify<T>()`](https://typia.io/docs/json/stringify/)
  - `validate.log`: [`typia.json.validateStringify<T>()`](https://typia.io/docs/json/stringify/), but do not throw error and just log it
  - `null`: just use `JSON.stringify()` function without validation

By the way, this is not a recommended way, but you can skip the response type validation for. If you set the `stringify` property to `null`, the response type validation will be skipped and just `JSON.stringify()` function be used. 

Also, `validate.log` performs the validation, but does not throw 500 internal server error. When type error be detected, it serializes response data by `JSON.stringify()` function, and logs the error message to the console or somewhere you've specified. It is useful when you want to know the error message, but do not want to throw 500 internal server error to the client application.

```typescript
TypedRoute.setValidateErrorLogger((err: TypedRoute.IValidateErrorLog) => {
  // you can customize the validation error logging
  console.error(err);
});
```

Additionally, if you configure `llm` property of the plugin, `@nestia/core` considers that your backend application has been developed for LLM function calling, and validates the request/response body types following the target LLM model's restrictions. 

For example, if you configure `chatgpt` with `strict` option, dynamic properties and optional properties are not allowed in the request/response body types. If your some request/response body types are not following the target LLM model's restrictions, `@nestia/core` will throw a compilation error.

Here is the list of available LLM models. Read their definitions, and follow their restrictions.

  - Supported schemas
    - `"chatgpt"`: ([`IChatGptSchema`](https://github.com/samchon/openapi/blob/master/src/structures/IChatGptSchema.ts)), OpenAI ChatGPT
    - `"claude"`: ([`IClaudeSchema`](https://github.com/samchon/openapi/blob/master/src/structures/IClaudeSchema.ts)), Anthropic Claude
    - `"gemini"`: ([`IGeminiSchema`](https://github.com/samchon/openapi/blob/master/src/structures/IGeminiSchema.ts)), Google Gemini
    - `"llama"`: ([`ILlamaSchema`](https://github.com/samchon/openapi/blob/master/src/structures/ILlamaSchema.ts)), Meta Llama
  - Midldle layer schemas
    - `"3.0"`: ([`ILlmSchemaV3`](https://github.com/samchon/openapi/blob/master/src/structures/ILlmSchemaV3.ts)), middle layer based on OpenAPI v3.0 specification
    - `"3.1"`: ([`ILlmSchemaV3_1`](https://github.com/samchon/openapi/blob/master/src/structures/ILlmSchemaV3_1.ts)), middle layer based on OpenAPI v3.1 specification




## Benchmark
### JSON
Comparing JSON serialization speed, [`typia`](https://typia.io/docs/json/stringify) is maximum 200x faster than `class-transformer`.

For reference, `Nestia` is using `typia`, and `NestJS` is using `class-transformer`. The other one `fast-json-stringify` is made and used by `fastify` (do not mean NestJS fastify mode, but mean pure `fastify` library. NestJS fastify mode still utilizes `class-transformer`), and it requires JSON schema definition.

From above benchmark graph, you can see that `class-transformer` is extremely slower than others, even including built-in `JSON.stringify()` function. I can't understand why `NestJS` has adopted such slow and difficult library. The other `fast-json-stringify` is enough faster, but it needs extra schema definition like `class-validator`, therefore not easy to use.

  - `typia` needs only pure TypeScript type.
  - `class-transformer` requires [DTO class with decorator function calls](https://github.com/samchon/typia/blob/master/benchmark/src/structures/class-validator/ClassValidatorObjectHierarchical.ts).
  - `fast-json-stringify` requires [JSON schema definition](https://github.com/samchon/typia/blob/master/test/schemas/json/swagger/ObjectHierarchical.json).

![Stringify Function Benchmark](https://github.com/samchon/typia/raw/master/benchmark/results/AMD%20Ryzen%209%207940HS%20w%20Radeon%20780M%20Graphics/images/stringify.svg)

> Measured on [AMD R9-7940HS, Rog Flow X13](https://github.com/samchon/typia/tree/master/benchmark/results/AMD%20Ryzen%209%207940HS%20w%20Radeon%20780M%20Graphics#stringify)

### Server
Looking at above benchmark, someone may ask:

> JSON serialization speed affects on the server performance? 
>
> I think that the JSON serialization is just a tiny thing in the server side, isn't it?

My answer is, "Yes, it affects on the server performance".

Most operations in NodeJS server are asynchronously executed in background thread, what are called "event based non-blocking I/O model". However, JSON serialization is a synchronous operation running on the main thread. Therefore, if the JSON serialization speed is slow, it makes the entire server program slow.

I'll show you the benchmark result that, how JSON serizliation speed affects on the server performance.

![Server Benchmark](https://raw.githubusercontent.com/samchon/nestia/master/benchmark/results/AMD%20Ryzen%209%207940HS%20w%20Radeon%20780M%20Graphics/images/stringify.svg)

> Measured on [AMD R9-7940HS, Rog Flow X13](https://github.com/samchon/nestia/tree/master/benchmark/results/AMD%20Ryzen%209%207940HS%20w%20Radeon%20780M%20Graphics#stringify)
